# 蓝牙操作

import time
from machine import Timer
import bluetooth

import zz_code
import zz_led
import zz_log
log = zz_log.of()

led = zz_led.of()


class ZZ_BLE():
    def __init__(self, name, event_callback=None):
        self.name = name
        if event_callback != None:
            self.event_callback = event_callback

        # 创建蓝牙
        self.ble = bluetooth.BLE()
        self.ble.active(True)  # 开启蓝牙
        self.ble.config(gap_name=name)  # 配置蓝牙信息
        self.ble.irq(self.event_handle)  # 绑定蓝牙事件
        self.register()  # 配置蓝牙的uuid
        # 发送接收文本长度
        self.msg_len_max = 20
        self.msg_data = b''  # 初始化接收文本
        self.conn_index = 0  # 猜是链接下标
        self.msg_end_eof = b'#'  # 文本结束符号，用于分段接收和发送
        self.enable = True

    def bind_callabck(self, event_callback):
        self.event_callback = event_callback

    # 蓝牙开始连接
    def init(self):
        # 蓝牙广播
        self.advertiser()
        # 蓝牙连接成功

    def connected(self):
        led.led_dodge_stop()
        led.led_blue(True)

    def service_close(self):
        log.debug(f"蓝牙服务关闭")
        self.enable = False

    def service_open(self):
        log.debug(f"蓝牙服务开启")
        self.enable = True

    # 蓝牙断开
    def connect_led(self):
        led.led_dodge(500)

    # 注册服务
    def register(self):
        service_uuid = '6E400001-B5A3-F393-E0A9-E50E24DCCA9E'
        reader_uuid = '6E400002-B5A3-F393-E0A9-E50E24DCCA9E'
        sender_uuid = '6E400003-B5A3-F393-E0A9-E50E24DCCA9E'

        services = (
            (
                bluetooth.UUID(service_uuid),
                (
                    (bluetooth.UUID(sender_uuid), bluetooth.FLAG_NOTIFY),
                    (bluetooth.UUID(reader_uuid), bluetooth.FLAG_WRITE),
                )
            ),
        )

        ((self.tx, self.rx,),) = self.ble.gatts_register_services(services)

    # 开始广播
    def advertiser(self):
        time.sleep_ms(100)
        self.service_open()

        log.debug("蓝牙开始广播")
        name = bytes(self.name, 'UTF-8')
        adv_data = adv_data = bytearray('\x02\x01\x02', 'UTF-8') + bytearray((len(name) + 1, 0x09), 'UTF-8') + name
        self.ble.gap_advertise(100, adv_data)
        self.connect_led()

    # 蓝牙回调事件
    def event_handle(self, event, data):
        log.debug(f"event_handle: {event},{self.enable}")

        if not self.enable:
            log.debug(f"蓝牙服务已关闭")
            return

        if event == 1:  # 手机连接了此设备
            log.debug("蓝牙连接成功")
            self.msg_data = b''

            self.connected()
        elif event == 2:  # 手机断开此设备
            log.debug("蓝牙连接失败")
            time.sleep_ms(100)
            self.advertiser()

        elif event == 3:  # 手机发送了数据
            conn_index, value_index = data
            self.conn_index = conn_index
            self.read_msg()

    # 分段发消息
    def send_msg(self, s):
        time.sleep_ms(100)  # 不延时会发送失败
        msg = s
        if isinstance(s, zz_code.Return):
            msg = s.to_json()

        log.debug(f"发送信息: {msg}")
        # 转二进制
        msg_data = bytes(msg, 'UTF-8')
        # 分段发送，1次最多20个字节
        for i in range(0, len(msg_data), self.msg_len_max):
            msg_inner = msg_data[i:i + self.msg_len_max]
            self.ble.gatts_notify(self.conn_index, 21, msg_inner)
        self.ble.gatts_notify(self.conn_index, 21, self.msg_end_eof)

    # 分段读消息
    def read_msg(self):
        # log.debug("read_msg")
        read_data = self.ble.gatts_read(self.rx)
        # log.debug(read_data)
        last_byte = read_data[len(read_data) - 1]
        # 分段接收1次最多20字节
        self.msg_data += read_data
        # #号为结束符，二进制35
        if (last_byte == self.msg_end_eof[0]):
            self.msg_data = self.msg_data[:len(self.msg_data) - 1]  # 去掉#符
            msg = self.msg_data.decode('UTF-8').strip()
            log.debug(f"接收信息：{msg}")
            self.msg_data = b''

            zz_code.thread_func(self.event_callback, msg)
            # callback = lambda t: self.event_callback(msg)
            # Timer(1).init(period=100, mode=Timer.ONE_SHOT, callback=callback)
